/**
 * Copyright (c) 2006-2017, JGraph Ltd
 * Copyright (c) 2006-2017, Gaudenz Alder
 */
/**
 * Class: mxTemporaryCellStates
 *
 * Creates a temporary set of cell states.
 */
function mxTemporaryCellStates (view, scale, cells, isCellVisibleFn, getLinkForCellState) {
  scale = (scale != null) ? scale : 1
  this.view = view

  // Stores the previous state
  this.oldValidateCellState = view.validateCellState
  this.oldBounds = view.getGraphBounds()
  this.oldStates = view.getStates()
  this.oldScale = view.getScale()
  this.oldDoRedrawShape = view.graph.cellRenderer.doRedrawShape

  var self = this

  // Overrides doRedrawShape and paint shape to add links on shapes
  if (getLinkForCellState != null) {
    view.graph.cellRenderer.doRedrawShape = function (state) {
      var oldPaint = state.shape.paint

      state.shape.paint = function (c) {
        var link = getLinkForCellState(state)

        if (link != null) {
          c.setLink(link)
        }

        oldPaint.apply(this, arguments)

        if (link != null) {
          c.setLink(null)
        }
      }

      self.oldDoRedrawShape.apply(view.graph.cellRenderer, arguments)
      state.shape.paint = oldPaint
    }
  }

  // Overrides validateCellState to ignore invisible cells
  view.validateCellState = function (cell, resurse) {
    if (cell == null || isCellVisibleFn == null || isCellVisibleFn(cell)) {
      return self.oldValidateCellState.apply(view, arguments)
    }

    return null
  }

  // Creates space for new states
  view.setStates(new mxDictionary())
  view.setScale(scale)

  if (cells != null) {
    view.resetValidationState()
    var bbox = null

    // Validates the vertices and edges without adding them to
    // the model so that the original cells are not modified
    for (var i = 0; i < cells.length; i++) {
      var bounds = view.getBoundingBox(view.validateCellState(view.validateCell(cells[i])))

      if (bbox == null) {
        bbox = bounds
      } else {
        bbox.add(bounds)
      }
    }

    view.setGraphBounds(bbox || new mxRectangle())
  }
};

/**
 * Variable: view
 *
 * Holds the width of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.view = null

/**
 * Variable: oldStates
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.oldStates = null

/**
 * Variable: oldBounds
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.oldBounds = null

/**
 * Variable: oldScale
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.oldScale = null

/**
 * Function: destroy
 *
 * Returns the top, left corner as a new <mxPoint>.
 */
mxTemporaryCellStates.prototype.destroy = function () {
  this.view.setScale(this.oldScale)
  this.view.setStates(this.oldStates)
  this.view.setGraphBounds(this.oldBounds)
  this.view.validateCellState = this.oldValidateCellState
  this.view.graph.cellRenderer.doRedrawShape = this.oldDoRedrawShape
}
